今日任務: 輸入關鍵字後,顯示所有與關鍵字相關的城市或景點
作者有給我們資料網址
const endpoint ='https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json'
這裡要使用 fetch 透過網路取得 json 然後印出在 console,最簡單的方式只需要一個參數就是資料的 URI,fetch 會回傳一個包含 response 的 promise 。
1. 獲取api
fetch(endpoint).then(function (response) {
console.log(response)
})
2.再將它轉成json檔使用
fetch(endpoint).then((response) => {
return response.json()
})
它會return資料,可以再繼續下一個.then使用
fetch(endpoint)
.then((response) => {
return response.json()
})
.then((data) => {
console.log(data)
})
將資料放進我們的cities陣列裡面(順便將函式簡寫)
let cities = []
fetch(endpoint)
.then((response) => response.json())
.then((data) => (cities = data))
如果你不想更改你的cities陣列,也可以用push
let cities = []
fetch(endpoint)
.then((response) => response.json())
.then((data) => cities.push(...data))
RegExp 物件被用來比對符合自訂規則的文字。new RegExp("pattern", "flag")
撰寫正規表達式時,使用兩個斜線 / /
或是 new RegExp()
來建立一個 RegExp 物件。
第一個參數放要搜尋的規律或內容
第二個參數放比對的方式
這邊放上詳細介紹
使用 String.prototype.match(regexp)
這個方法來判斷給的字串當中是否有符合該 regexp pattern 的內容,有的話以陣列回傳,沒有的話回傳 null。
比對city和state兩種
function findMatches(wordToMarch, cities) {
return cities.filter((place) => {
//找出和關鍵字相符合的城市或景點
const regex = new RegExp(wordToMarch, 'gi')
return place.city.match(regex) || place.state.match(regex)
})
}
const searchInput = document.querySelector('.search')
searchInput.addEventListener('keyup', rederMatches)
searchInput.addEventListener('change', rederMatches)
function rederMatches() {
console.log(this.value)
}
將文字內容進行比對
function rederMatches() {
const matchArray = findMatches(this.value, cities)
console.log(matchArray)
}
const suggestions = document.querySelector('.suggestions')
function rederMatches() {
const matchArray = findMatches(this.value, cities)
console.log(matchArray)
const html = matchArray.map((place) => {
return `
<li>
<span class="name">${place.city}, ${place.state}</span>
<span class="population">${place.population}</span>
</li>`
})
suggestions.innerHTML = html
}
畫面上會出現逗號
會將陣列(或一個類陣列(array-like)物件)中所有的元素連接、合併成一個字串,並回傳此字串。
function rederMatches() {
const matchArray = findMatches(this.value, cities)
console.log(matchArray)
const html = matchArray.map((place) => {
return `
<li>
<span class="name">${place.city}, ${place.state}</span>
<span class="population">${place.population}</span>
</li>`
}).join('')
suggestions.innerHTML = html
}
replace()
方法會傳回一個新字串,此新字串是透過將原字串與 pattern
比對,以 replacement
取代吻合處而生成。pattern
可以是字串或 RegExp,而 replacement
可以是字串或函式(會在每一次匹配時被呼叫)。//關鍵字
const regex = new RegExp(this.value, 'gi')
//將關鍵字highlight出來
const cityName = place.city.replace(regex, `<span class="highlight">${this.value}</span>`)
console.log(cityName)
function rederMatches() {
const matchArray = findMatches(this.value, cities)
const html = matchArray.map((place) => {
//關鍵字
const regex = new RegExp(this.value, 'gi')
//將關鍵字highlight出來
const cityName = place.city.replace(regex, `<span class="highlight">${this.value}</span>`)
const stateName = place.state.replace(regex, `<span class="highlight">${this.value}</span>`)
return `
<li>
<span class="name">${cityName}, ${stateName}</span>
<span class="population">${place.population}</span>
</li>`
}).join('')
suggestions.innerHTML = html
}
\B(?=(\d{3})+(?!\d))是作者直接貼上的正規表達式
參考
十五分鐘認識正規表達式,解決所有文字難題
將數字加上 comma 的正規表達式說明
\B 比對非文字邊界,包括空格及特別字元。
A(?=B) → A 後方的條件要符合 B
\d 比對一個數字,相等於 /[0-9]/
A(?!B) → A 後方的條件不能符合 B
所以\B(?=(\d{3})+(?!\d))
可拆解為\d{3} =\d\d\d
,比對 3 個連續的數字(\d{3})+
代表匹配一次或多次連續 3 個數字\B(?=(\d{3})+
非文字邊界(下圖藍線)後要匹配一次或多次連續 3 個數字(紅色箭頭為藍線3個一數)(?!\d)
後方不能再有數字
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
放到我們的渲染函式中
return
`<li>
<span class="name">${cityName}, ${stateName}</span>
<span class="population">${numberWithCommas(place.population)}</span>
</li>`
今日學習到的:
效果連結:連結
參考連結:
MDN: Fetch
MDN: RegExp
String.prototype.match()
正規表示法(Regular expressions)
pjchender: 正則表達式
MDN: join()
MDN: replace()
正規表達式(RegExp)
十五分鐘認識正規表達式,解決所有文字難題
將數字加上 comma 的正規表達式說明